import type {
  typ_event_keys,
  typ_seek_listenInfo_by_type_arr,
  typ_seek_listenInfo_keyVal,
  typ_seek_listenInfo_type,
} from '../Types';
import { listenEvent_info } from './cla_listenEvent_info';

const listenEvent_info_manaTag = 'listenEvent_info_mana';

export class listenEvent_info_mana {
  get [Symbol.toStringTag]() {
    return listenEvent_info_manaTag;
  }

  constructor() {}

  /**
   * 挂载 中 的 事件 栈
   */
  stack: listenEvent_info[] = [];

  /**
   * 添加 事件 信息
   */
  addInfo(targetEl: HTMLElement, event: typ_event_keys, fn: Function) {
    this.stack.unshift(new listenEvent_info(targetEl, event, fn));
  }

  /**
   * 移除 事件 信息
   */
  removeInfo(targetEl: HTMLElement, event: typ_event_keys, fn: Function) {
    let deleteArr = this.seekForStack(targetEl, event, fn);
    for (const uniInfo of deleteArr) {
      let ind = this.stack.indexOf(uniInfo);
      this.stack.splice(ind, 1);
    }
    return deleteArr;
  }

  /**
   * 根据 元素 事件 函数 (三个可以自由组合)
   * 选取 对应的 信息集
   */
  seekForStack(
    targetEl: HTMLElement | undefined,
    event: typ_event_keys,
    fn: Function
  ) {
    let ret = this.stack;

    if (targetEl) {
      ret = seekForProp(ret, 'targetEl', targetEl);
    }

    if (event) {
      ret = seekForProp(ret, 'event', event);
    }

    if (fn) {
      ret = seekForProp(ret, 'fn', fn);
    }

    return ret;
  }
}

/**
 * 根据 stack 数据 查询 相关 数组
 */
function seekForProp(
  stack: listenEvent_info[],
  prop: typ_seek_listenInfo_type,
  val: typ_seek_listenInfo_keyVal
) {
  let ret = [];

  for (const uniInfo of stack) {
    if (uniInfo[prop] == val) {
      ret.push(uniInfo);
    }
  }

  return ret;
}

// /**
//  *
//  * 根据 stack 数据 查询 相关 数组
//  */
// function forof_seekForProp(
//   listen_info: listenEvent_info[],
//   prop: typ_seek_listenInfo_type,
//   val: typ_seek_listenInfo_keyVal
// ) {
//   let ret = seekForProp(listen_info, prop, val);
//   return ret;
// }

/**
 * 根据 可能 数组情况 获取 对应 数据
 */
export function locate_uniArr_info(
  listen_info: listenEvent_info[],
  { targetElArr, eventArr, fnArr }: typ_seek_listenInfo_by_type_arr
) {
  let ret = [];
  if (targetElArr != undefined) {
    if (is_other_option(targetElArr) || targetElArr instanceof HTMLElement) {
      targetElArr = [targetElArr];
    }

    for (const target of targetElArr) {
      ret.push(...seekForProp(listen_info, 'targetEl', target));
    }
    listen_info = ret;
  }

  if (eventArr != undefined) {
    ret = [];
    // 未测试
    if (typeof eventArr == 'string') {
      eventArr = [eventArr];
    }

    for (const event of eventArr) {
      ret.push(...seekForProp(listen_info, 'event', event));
    }

    listen_info = ret;
  }

  if (fnArr != undefined) {
    ret = [];
    // 未测试
    if (typeof fnArr == 'function') {
      fnArr = [fnArr];
    }
    for (const fn of fnArr) {
      ret.push(...seekForProp(listen_info, 'fn', fn));
    }
  }

  return ret;
}

function is_other_option(cur_target: any): cur_target is HTMLElement {
  if (cur_target == window) return true;

  return false;
}
